home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / ipcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-07  |  12.9 KB  |  518 lines

  1. /* IP-related user commands */
  2. #include <stdio.h>
  3. #include "global.h"
  4. #include "mbuf.h"
  5. #include "internet.h"
  6. #include "timer.h"
  7. #include "netuser.h"
  8. #include "iface.h"
  9. #include "ip.h"
  10. #include "cmdparse.h"
  11. #include "commands.h"
  12. #include "socket.h"
  13. #include "config.h"
  14.  
  15. #ifdef IPACCESS
  16. static int doaccess __ARGS((int argc,char *argv[],void *p));
  17. #endif
  18. char RouteHeader[] = "Destination     Len Interface    Gateway          Metric  P Timer  Use\n";
  19.  
  20. /* Dump a routing table entry */
  21. int near
  22. dumproute(struct route *rp)
  23. {
  24.     tprintf("%-16s%-4u",
  25.         (rp->target != 0) ? inet_ntoa(rp->target) : "default",rp->bits);
  26.     tprintf("%-13s%-17s",
  27.         rp->iface->name,(rp->gateway != 0) ? inet_ntoa(rp->gateway) : "");
  28.     tprintf("%-8lu%c %-7lu%lu\n",
  29.         rp->metric,(rp->flags & RTPRIVATE) ? 'P' : ' ',
  30.         read_timer(&rp->timer)/1000L,rp->uses);
  31.     return;
  32. }
  33.  
  34.  
  35.  
  36. /* ------------------------ IP subcmds ------------------------ */
  37.  
  38. static int
  39. doipaddr(argc,argv,p)
  40. int argc;
  41. char *argv[];
  42. void *p;
  43. {
  44.     int32 n;
  45.  
  46.     if(argc < 2) {
  47.         tprintf("%s\n",inet_ntoa(Ip_addr));
  48.     } else if((n = resolve(argv[1])) == 0){
  49.         tprintf(Badhost,argv[1]);
  50.         return 1;
  51.     } else
  52.         Ip_addr = n;
  53.     return 0;
  54. }
  55.  
  56. static int
  57. dortimer(argc,argv,p)
  58. int argc;
  59. char *argv[];
  60. void *p;
  61. {
  62.     return setlong(&ipReasmTimeout,"IP reasm timeout (sec)",argc,argv);
  63. }
  64.  
  65. static int
  66. doipstat(argc,argv,p)
  67. int argc;
  68. char *argv[];
  69. void *p;
  70. {
  71.     struct reasm *rp;
  72.     struct frag *fp;
  73.     int i;
  74.  
  75.     for(i = 1; i <= NUMIPMIB; i++){
  76.         tprintf("(%2u)ip%-18s%10lu",
  77.             i,Ip_mib[i].name,Ip_mib[i].value.integer);
  78.         tputs((i % 2) ? "     " : "\n");
  79.     }
  80.     if((i % 2) == 0)
  81.         tputs("\n");
  82.  
  83.     if(Reasmq != NULLREASM) {
  84.         tputs("Reassembly fragments:\n");
  85.         for(rp = Reasmq; rp != NULLREASM; rp = rp->next){
  86.             tprintf("src %s",inet_ntoa(rp->source));
  87.             tprintf(" dest %s",inet_ntoa(rp->dest));
  88.             tprintf(" id %u pctl %u time %lu len %u\n",
  89.                 rp->id,uchar(rp->protocol),read_timer(&rp->timer),rp->length);
  90.             for(fp = rp->fraglist; fp != NULLFRAG; fp = fp->next)
  91.                 tprintf(" offset %u last %u\n",fp->offset,fp->last);
  92.         }
  93.     }
  94.     return 0;
  95. }
  96.  
  97. static int
  98. dottl(argc,argv,p)
  99. int argc;
  100. char *argv[];
  101. void *p;
  102. {
  103.     return setlong(&ipDefaultTTL,"IP TTL",argc,argv);
  104. }
  105.  
  106. int
  107. doip(argc,argv,p)
  108. int argc;
  109. char *argv[];
  110. void *p;
  111. {
  112.     static struct cmds Ipcmds[] = {
  113. #ifdef IPACCESS
  114.         "access",    doaccess,    0,    0, NULLCHAR,
  115. #endif
  116.         "address",    doipaddr,    0,    0, NULLCHAR,
  117.         "rtimer",    dortimer,    0,    0, NULLCHAR,
  118.         "status",    doipstat,    0,    0, NULLCHAR,
  119.         "ttl",        dottl,        0,    0, NULLCHAR,
  120.         NULLCHAR,
  121.     };
  122.     return subcmd(Ipcmds,argc,argv,p);
  123. }
  124.  
  125.  
  126. /* --------------------------- route subcmds ------------------------ */
  127.  
  128. /* Add an entry to the routing table
  129.  * E.g., "add 1.2.3.4 ax0 5.6.7.8 3"
  130.  */
  131. static int
  132. doadd(argc,argv,p)
  133. int argc;
  134. char *argv[];
  135. void *p;
  136. {
  137.     struct iface *ifp;
  138.     int32 dest,gateway;
  139.     unsigned bits;
  140.     char *bitp;
  141.     int32 metric;
  142.     char private;
  143.  
  144.     private = (strncmp(argv[0],"addp",4) == 0) ? 1 : 0;
  145.  
  146.     if(strcmp(argv[1],"default") == 0){
  147.         bits = 0;
  148.         dest = 0L;
  149.     } else {
  150.         /* If IP address is followed by an optional slash and
  151.          * a length field, (e.g., 128.96/16) get it;
  152.          * otherwise assume a full 32-bit address
  153.          */
  154.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  155.             /* Terminate address token for resolve() call */
  156.             *bitp++ = '\0';
  157.             bits = atoi(bitp);
  158.         } else
  159.             bits = 32;
  160.  
  161.         if((dest = resolve(argv[1])) == 0){
  162.             tprintf(Badhost,argv[1]);
  163.             return 1;
  164.         }
  165.     }
  166.     if((ifp = if_lookup(argv[2])) == NULLIF){
  167.         tprintf(Badif,argv[2]);
  168.         return 1;
  169.     }
  170.     if(argc > 3){
  171.         if((gateway = resolve(argv[3])) == 0){
  172.             tprintf(Badhost,argv[3]);
  173.             return 1;
  174.         }
  175.     } else {
  176.         gateway = 0;
  177.     }
  178.     metric = (argc > 4) ? atol(argv[4]) : 1;
  179.  
  180.     if(rt_add(dest,bits,gateway,ifp,metric,0,private) == NULLROUTE)
  181.         tputs("Can't add route\n");
  182.     return 0;
  183. }
  184.  
  185. /* Drop an entry from the routing table
  186.  * E.g., "drop 128.96/16
  187.  */
  188. static int
  189. dodrop(argc,argv,p)
  190. int argc;
  191. char *argv[];
  192. void *p;
  193. {
  194.     char *bitp;
  195.     unsigned bits;
  196.     int32 n;
  197.  
  198.     if(strcmp(argv[1],"default") == 0){
  199.         n = 0;
  200.         bits = 0;
  201.     } else {
  202.         /* If IP address is followed by an optional slash and length field,
  203.          * (e.g., 128.96/16) get it; otherwise assume a full 32-bit address
  204.          */
  205.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  206.             *bitp++ = '\0';
  207.             bits = atoi(bitp);
  208.         } else
  209.             bits = 32;
  210.  
  211.         if((n = resolve(argv[1])) == 0){
  212.             tprintf(Badhost,argv[1]);
  213.             return 1;
  214.         }
  215.     }
  216.     return rt_drop(n,bits);
  217. }
  218.  
  219. /* Force a timeout on all temporary routes */
  220. static int
  221. doflush(argc,argv,p)
  222. int argc;
  223. char *argv[];
  224. void *p;
  225. {
  226.     struct route *rp;
  227.     struct route *rptmp;
  228.     int i,j;
  229.  
  230.     if(R_default.timer.state == TIMER_RUN){
  231.         rt_drop(0,0);    /* Drop default route */
  232.     }
  233.     for(i = 0; i < HASHMOD; i++) {
  234.         for(j=0;j<32;j++){
  235.             for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
  236.                 rptmp = rp->next;
  237.                 if(rp->timer.state == TIMER_RUN){
  238.                     rt_drop(rp->target,rp->bits);
  239.                 }
  240.             }
  241.         }
  242.     }
  243.     return 0;
  244. }
  245.  
  246. static int
  247. dolook(argc,argv,p)
  248. int argc;
  249. char *argv[];
  250. void *p;
  251. {
  252.     struct route *rp;
  253.     int32 addr;
  254.  
  255.     if((addr = resolve(argv[1])) == 0) {
  256.         tprintf(Badhost,argv[1]);
  257.         return 1;
  258.     }
  259.     if((rp = rt_lookup(addr)) == NULLROUTE){
  260.         tprintf("Host %s (%s) unreachable\n",argv[1],inet_ntoa(addr));
  261.         return 1;
  262.     }
  263.     dumproute(rp);
  264.     return 0;
  265. }
  266.  
  267. /* Display and/or manipulate routing table */
  268. int
  269. doroute(argc,argv,p)
  270. int argc;
  271. char *argv[];
  272. void *p;
  273. {
  274.     int i, bits;
  275.     struct route *rp;
  276.  
  277.     struct cmds Rtcmds[] = {
  278.         "add",        doadd,        0,    3,
  279.         "route add <dest addr>[/<bits>] <iface> [gateway] [metric]",
  280.  
  281.         "addprivate",    doadd,        0,    3,
  282.         "route addprivate <dest addr>[/<bits>] <iface> [gateway] [metric]",
  283.  
  284.         "drop",        dodrop,        0,    2,
  285.         "route drop <dest addr>[/<bits>]",
  286.  
  287.         "flush",    doflush,    0,    0,
  288.         NULLCHAR,
  289.  
  290.         "lookup",    dolook,        0,    2,
  291.         "route lookup <dest addr>",
  292.  
  293.         NULLCHAR,
  294.     };
  295.  
  296.     if(argc >= 2)
  297.         return subcmd(Rtcmds,argc,argv,p);
  298.  
  299.     /* Dump IP routing table
  300.      * Dest            Len Interface    Gateway          Use
  301.      * 192.001.002.003 32  sl0          192.002.003.004  0
  302.      */
  303.     tputs(RouteHeader);
  304.  
  305.     for(bits = 31; bits >= 0; bits--) {
  306.         for(i = 0; i < HASHMOD; i++) {
  307.             for(rp = Routes[bits][i];rp != NULLROUTE;rp = rp->next){
  308.                 if(dumproute(rp) == EOF)
  309.                     return 0;
  310.             }
  311.         }
  312.     }
  313.     if(R_default.iface != NULLIF)
  314.         dumproute(&R_default);
  315.  
  316.     return 0;
  317. }
  318.  
  319. #ifdef  IPACCESS
  320. static int
  321. doaccess(argc,argv,p)
  322. int argc;
  323. char *argv[];
  324. void *p;
  325. {
  326.     struct iface *ifp;
  327.     int32 source,target;
  328.     unsigned sbits,tbits;
  329.     char *bitp;
  330.     int16 lport,hport,protocol,state;
  331.     char *cp; /* for printing the table */
  332.     struct rtaccess *tpacc;
  333.     struct rtaccess *btacc;
  334.     struct rtaccess *bfacc;
  335.     struct rtaccess *head;
  336.     char tmpbuf[15];
  337.   
  338.     if(argc == 1){ /* print out the table */
  339.         tputs("Source Address  Len Dest Address    Len Interface    Proto   Low  High State\n");
  340.         for(tpacc = IPaccess;tpacc != NULLACCESS;tpacc = tpacc->nxtiface){
  341.             for(btacc = tpacc;btacc != NULLACCESS;btacc = btacc->nxtbits){
  342.                 if(btacc->source != 0)
  343.                     cp = inet_ntoa(btacc->source);
  344.                 else
  345.                     cp = "all";
  346.                 tprintf("%-16s",cp);
  347.                 tprintf("%2u  ",btacc->sbits);
  348.                 if(btacc->target != 0)
  349.                     cp = inet_ntoa(btacc->target);
  350.                 else
  351.                     cp = "all";
  352.                 tprintf("%-16s",cp);
  353.                 tprintf("%2u  ",btacc->bits);
  354.                 tprintf("%-13s",btacc->iface->name);
  355.                 switch (btacc->protocol) {
  356.                     case 0:
  357.                         cp = "any";
  358.                         break;
  359.                     case ICMP_PTCL:
  360.                         cp = "icmp";
  361.                         break;
  362.                     case TCP_PTCL:
  363.                         cp = "tcp";
  364.                         break;
  365.                     case UDP_PTCL:
  366.                         cp = "udp";
  367.                         break;
  368.                     default:
  369.                         cp = itoa(btacc->protocol,tmpbuf,10);
  370.                 }
  371.                 tprintf("%-5s ",cp);
  372.                 tprintf("%5u ",btacc->lowport);
  373.                 tprintf("%5u ",btacc->highport);
  374.                 if(btacc->status)
  375.                     cp = "deny";
  376.                 else
  377.                     cp = "permit";
  378.                 tprintf("%-6s\n",cp);
  379.             }
  380.         }
  381.         return 0;
  382.     }
  383.   
  384.     if(strcmp(argv[1],"permit") == 0){
  385.         state = 0;
  386.     } else {
  387.         if((strcmp(argv[1],"deny") == 0)
  388.         || (strcmp(argv[1],"delete") == 0)){
  389.             state = -1;
  390.         } else {
  391.             tputs("Format: ip access <permit|deny|delete> <proto> <src addr>[/<bits>] <dest addr>[/<bits>] <if name> [low [high]]\n");
  392.             return 1;
  393.         }
  394.     }
  395.   
  396.     switch (*argv[2]){
  397.         case 'a':       /* ANY */
  398.             protocol = 0;
  399.             break;
  400.         case 'i':       /* ICMP */
  401.             protocol = ICMP_PTCL;
  402.             break;
  403.         case 't':       /* TCP */
  404.             protocol = TCP_PTCL;
  405.             break;
  406.         case 'u':       /* UDP */
  407.             protocol = UDP_PTCL;
  408.             break;
  409.         default:
  410.             protocol = atoi(argv[2]);
  411.     }
  412.   
  413.     if(strcmp(argv[3],"all") == 0){
  414.         source = 0;
  415.         sbits = 0;
  416.     } else {
  417.         /* If IP address is followed by an optional slash and
  418.          * a length field, (e.g., 128.96/16) get it;
  419.          * otherwise assume a full 32-bit address
  420.          */
  421.         if((bitp = strchr(argv[3],'/')) != NULLCHAR){
  422.             /* Terminate address token for resolve() call */
  423.             *bitp++ = '\0';
  424.             sbits = atoi(bitp);
  425.         } else
  426.             sbits = 32;
  427.   
  428.         if((source = resolve(argv[3])) == 0){
  429.             tprintf(Badhost,argv[3]);
  430.             return 1;
  431.         }
  432.     }
  433.     if(strcmp(argv[4],"all") == 0){
  434.         target = 0;
  435.         tbits = 0;
  436.     } else {
  437.         if((bitp = strchr(argv[4],'/')) != NULLCHAR){
  438.             *bitp++ = '\0';
  439.             tbits = atoi(bitp);
  440.         } else
  441.             tbits = 32;
  442.   
  443.         if((target = resolve(argv[4])) == 0){
  444.             tprintf(Badhost,argv[4]);
  445.             return 1;
  446.         }
  447.     }
  448.   
  449.     if((ifp = if_lookup(argv[5])) == NULLIF){
  450.         tprintf(Badif,argv[5]);
  451.         return 1;
  452.     }
  453.   
  454.     if(((protocol != TCP_PTCL) && (protocol != UDP_PTCL)) || (argc < 7)) {
  455.         lport = 0;
  456.         hport = 0;
  457.     } else {
  458.         if(strcmp(argv[6],"all") == 0){
  459.             lport = 0;
  460.         } else {
  461.             lport = atoi(argv[6]);
  462.         }
  463.         if((argc < 8) || (lport == 0))
  464.             hport = lport;
  465.         else
  466.             hport = atoi(argv[7]);
  467.     }
  468.   
  469.     if(strcmp(argv[1],"delete") == 0){
  470.         head = IPaccess;
  471.         for(tpacc = IPaccess;tpacc != NULLACCESS;head = tpacc,tpacc = tpacc->nxtiface){
  472.             if(tpacc->iface == ifp){
  473.                 for(btacc = tpacc;btacc != NULLACCESS;
  474.                 head = btacc,btacc = btacc->nxtbits){
  475.                     if((btacc->protocol == protocol) &&
  476.                         (btacc->source == source)     &&
  477.                         (btacc->sbits == sbits)       &&
  478.                         (btacc->target == target)     &&
  479.                         (btacc->bits == tbits)        &&
  480.                         (btacc->lowport == lport)     &&
  481.                     (btacc->highport == hport)) { /*match*/
  482.                         bfacc = btacc; /* save to unalloc */
  483.                 /*now delete. watch for special cases*/
  484.                         if(btacc != tpacc){ /* not at head of list */
  485.                             head->nxtbits = btacc->nxtbits;
  486.                             free(bfacc);
  487.                             return 0;
  488.                         }
  489.                         if(btacc == IPaccess){ /* real special case */
  490.                             if(IPaccess->nxtbits == NULLACCESS)
  491.                                 IPaccess = btacc->nxtiface;
  492.                             else {
  493.                                 IPaccess = btacc->nxtbits;
  494.                                 (btacc->nxtbits)->nxtiface = btacc->nxtiface;
  495.                             }
  496.                         } else { /* we know tpacc=btacc <> IPaccess */
  497.                             if(btacc->nxtbits == NULLACCESS)
  498.                                 head->nxtiface = btacc->nxtiface;
  499.                             else {
  500.                                 head->nxtiface = btacc->nxtbits;
  501.                                 (btacc->nxtbits)->nxtiface = btacc->nxtiface;
  502.                             }
  503.                         }
  504.                         free(bfacc);
  505.                         return 0;
  506.                     }
  507.                 }
  508.             }
  509.         }
  510.         tputs("Not found.\n");
  511.         return 1;
  512.     }
  513.     /* add the access */
  514.     addaccess(protocol,source,sbits,target,tbits,ifp,lport,hport,state);
  515.     return 0;
  516. }
  517. #endif
  518.